package websocket

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"sync"
	"time"

	"github.com/gorilla/websocket"
	"github.com/zeromicro/go-zero/core/logx"
)

// 房间广播消息
func (r *Room) Broadcast(message Message) {
	// 添加到历史记录
	r.addMessage(message)

	// 序列化为JSON
	messageBytes, err := json.Marshal(message)
	if err != nil {
		logx.Errorf("[Room.Broadcast] JSON序列化失败: %v", err)
		return
	}

	// 广播给所有客户端
	r.Mu.RLock()
	clients := make([]*Client, 0, len(r.Clients))
	for _, client := range r.Clients {
		clients = append(clients, client)
	}
	r.Mu.RUnlock()

	var wg sync.WaitGroup
	for _, client := range clients {
		wg.Add(1)
		go func(c *Client) {
			defer wg.Done()
			if err := c.SendMessage(messageBytes); err != nil {
				logx.Errorf("[Room.Broadcast] 发送消息给客户端 %s 失败: %v", c.UserID, err)
				// 移除无法发送消息的客户端
				r.RemoveClient(c)
			}
		}(client)
	}
	wg.Wait()
}

// 游戏房间广播消息
func (r *GameRoom) Broadcast(message Message) {
	// 添加到历史记录（非游戏状态消息）
	if message.Type != int(MessageTypeGameState) {
		r.addMessage(message)
	}

	// 序列化为JSON
	messageBytes, err := json.Marshal(message)
	if err != nil {
		logx.Errorf("[GameRoom.Broadcast] JSON序列化失败: %v", err)
		return
	}

	// 广播给所有客户端
	r.mu.RLock()
	clients := make([]*Client, 0, len(r.Clients))
	for _, client := range r.Clients {
		clients = append(clients, client)
	}
	r.mu.RUnlock()

	var wg sync.WaitGroup
	for _, client := range clients {
		wg.Add(1)
		go func(c *Client) {
			defer wg.Done()
			if err := c.SendMessage(messageBytes); err != nil {
				logx.Errorf("[GameRoom.Broadcast] 发送消息给客户端 %s 失败: %v", c.UserID, err)
				// 移除无法发送消息的客户端
				r.RemoveClient(c)
			}
		}(client)
	}
	wg.Wait()
}

// 广播游戏状态
func (r *GameRoom) BroadcastGameState() {
	r.gameMu.RLock()
	stateCopy := r.GameState
	r.gameMu.RUnlock()

	if stateCopy == nil {
		logx.Error("[GameRoom.BroadcastGameState] 游戏状态为空")
		return
	}

	// 序列化游戏状态
	stateBytes, err := json.Marshal(stateCopy)
	if err != nil {
		logx.Errorf("[GameRoom.BroadcastGameState] 游戏状态序列化失败: %v", err)
		return
	}

	// 创建游戏状态消息
	message := Message{
		Type:    int(MessageTypeGameState),
		Content: string(stateBytes),
		Time:    time.Now().Unix(),
	}

	// 广播消息
	r.Broadcast(message)
}

// 安全发送消息到客户端
func (c *Client) SendMessage(data []byte) error {
	c.Mu.Lock()
	defer c.Mu.Unlock()

	if c.Conn == nil {
		return fmt.Errorf("客户端连接已关闭")
	}

	// 设置写入超时
	c.Conn.SetWriteDeadline(time.Now().Add(10 * time.Second))

	// 发送消息
	return c.Conn.WriteMessage(websocket.TextMessage, data)
}

// 添加消息到历史记录
func (r *Room) addMessage(message Message) {
	r.Mu.Lock()
	defer r.Mu.Unlock()

	// 生成唯一消息ID
	message.ID = generateMessageID()

	// 添加到历史记录
	if r.Messages == nil {
		r.Messages = make([]*Message, 0, 100)
	}
	r.Messages = append(r.Messages, &message)

	// 限制消息数量
	maxMessages := 1000
	if len(r.Messages) > maxMessages {
		r.Messages = r.Messages[len(r.Messages)-maxMessages:]
	}

	// 异步保存到数据库
	if r.wsServer != nil && r.wsServer.DB != nil {
		go func(msg Message) {
			// TODO: 实现models.SaveMessage函数
			// if err := models.SaveMessage(r.wsServer.DB, &msg, r.ID); err != nil {
			// 	logx.Errorf("保存消息到数据库失败: %v", err)
			// }
		}(message)
	}
}

// 添加消息到游戏房间历史记录
func (r *GameRoom) addMessage(message Message) {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 生成唯一消息ID
	message.ID = generateMessageID()

	// 添加到历史记录
	if r.Messages == nil {
		r.Messages = make([]*Message, 0, 100)
	}
	r.Messages = append(r.Messages, &message)

	// 限制消息数量
	maxMessages := 1000
	if len(r.Messages) > maxMessages {
		r.Messages = r.Messages[len(r.Messages)-maxMessages:]
	}

	// 异步保存到数据库
	// if r.wsServer != nil && r.wsServer.DB != nil {
	// 	go func(msg Message) {
	// 		// TODO: 实现models.SaveMessage函数
	// 		// if err := models.SaveMessage(r.wsServer.DB, &msg, r.ID); err != nil {
	// 		// 	logx.Errorf("保存游戏房间消息到数据库失败: %v", err)
	// 		// }
	// 	}(message)
	// }
}

// 获取历史消息
func (r *Room) getMessages(beforeID string, limit int) []*Message {
	r.Mu.RLock()
	defer r.Mu.RUnlock()

	if r.Messages == nil || len(r.Messages) == 0 {
		return []*Message{}
	}

	// 如果没有指定beforeID，返回最新的limit条消息
	if beforeID == "" {
		start := 0
		if len(r.Messages) > limit {
			start = len(r.Messages) - limit
		}
		return r.Messages[start:]
	}

	// 查找beforeID对应的索引
	index := -1
	for i, msg := range r.Messages {
		if msg.ID == beforeID {
			index = i
			break
		}
	}

	// 如果没找到，返回空
	if index == -1 {
		return []*Message{}
	}

	// 计算起始索引
	start := 0
	if index > limit {
		start = index - limit
	}

	// 返回结果
	return r.Messages[start:index]
}

// 获取游戏房间历史消息
func (r *GameRoom) getMessages(beforeID string, limit int) []*Message {
	r.mu.RLock()
	defer r.mu.RUnlock()

	if r.Messages == nil || len(r.Messages) == 0 {
		return []*Message{}
	}

	// 如果没有指定beforeID，返回最新的limit条消息
	if beforeID == "" {
		start := 0
		if len(r.Messages) > limit {
			start = len(r.Messages) - limit
		}
		return r.Messages[start:]
	}

	// 查找beforeID对应的索引
	index := -1
	for i, msg := range r.Messages {
		if msg.ID == beforeID {
			index = i
			break
		}
	}

	// 如果没找到，返回空
	if index == -1 {
		return []*Message{}
	}

	// 计算起始索引
	start := 0
	if index > limit {
		start = index - limit
	}

	// 返回结果
	return r.Messages[start:index]
}

// 设置消息已读
func (r *Room) setMessageRead(userID, messageID string) {
	// 异步更新数据库
	// if r.wsServer != nil && r.wsServer.DB != nil {
	// 	go func() {
	// 		// TODO: 实现models.SetMessageRead函数
	// 		// if err := models.SetMessageRead(r.wsServer.DB, userID, messageID); err != nil {
	// 		// 	logx.Errorf("设置消息已读失败: %v", err)
	// 		// }
	// 	}()
	// }
}

// 生成唯一消息ID
func generateMessageID() string {
	return fmt.Sprintf("msg-%d-%d", time.Now().UnixNano(), rand.Int63n(1000000))
}
